package com.flying.utils.excel;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;

import java.util.Date;
import java.util.regex.Pattern;

public final class ExcelUtil {
    /**
     * @param cell org.apache.poi.ss.usermodel.Cell
     * @return false, when null or BLANK or empty string("", STRING OR FORMULA); true , when NUMERIC, BOOLEAN,
     */
    public static boolean isEmpty(Cell cell) {
        if (cell == null) return true;
        CellType cellType = cell.getCellTypeEnum();
        switch (cellType) {
            case STRING:
                return StringUtils.isEmpty(StringUtils.trimToEmpty(cell.getStringCellValue()));
            case FORMULA:
                return StringUtils.isEmpty(StringUtils.trimToEmpty(cell.getCellFormula()));
            case BLANK:
                return true;
            case BOOLEAN:
            case NUMERIC:
            case ERROR:
                return false;
            default:
                throw new RuntimeException("Unexpected cell type (" + cellType + ") in isEmpty.");
        }
    }

    /**
     * @param cell org.apache.poi.ss.usermodel.Cell
     * @return true, when ERROR. otherwise return false;
     */
    public static boolean isError(Cell cell) {
        return cell != null && cell.getCellTypeEnum() == CellType.ERROR;
    }

    public static double asDouble(Cell cell) {
        if (cell == null) return 0;
        CellType cellType = cell.getCellTypeEnum();
        switch (cellType) {
            case NUMERIC:
                return cell.getNumericCellValue();
            case STRING:
                String value = StringUtils.trimToEmpty(cell.getStringCellValue());
                return StringUtils.isEmpty(value) ? 0 : Double.valueOf(value);
            case BLANK:
                return 0;
            case BOOLEAN:
            case ERROR:
            case FORMULA:
            default:
                throw new RuntimeException("Unexpected cell type (" + cellType + ") in asDouble");
        }
    }

    public static Date asDate(Cell cell) {
        if (cell == null) return null;
        CellType cellType = cell.getCellTypeEnum();
        switch (cellType) {
            case NUMERIC:
                return cell.getDateCellValue();
            case BLANK:
                return null;
            case STRING:
            case BOOLEAN:
            case ERROR:
            case FORMULA:
            default:
                throw new RuntimeException("Unexpected cell type (" + cellType + ") in asDate");
        }
    }

    public static String asString(Cell cell) {
        if (cell == null) return StringUtils.EMPTY;
        CellType cellType = cell.getCellTypeEnum();
        switch (cellType) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf(cell.getNumericCellValue());
            case BLANK:
                return StringUtils.EMPTY;
            case FORMULA:
                return cell.getCellFormula();
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case ERROR:
                return String.valueOf(cell.getErrorCellValue());
            default:
                throw new RuntimeException("Unexpected cell type (" + cellType + ") in asString");
        }
    }

    public static int indexOf(Row row, String content) {
        for (Cell cell : row) {
            if (Pattern.matches(content, asString(cell))) return cell.getColumnIndex();
        }
        return -1;
    }

    public static Cell firstCell(Row row, String pattern) {
        for (Cell cell : row) {
            if (Pattern.matches(pattern, asString(cell))) return cell;
        }
        return null;
    }
}